package org.openintents.droidcon.cloud.model;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.Order;
import javax.jdo.annotations.Extension;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import org.apache.commons.collections.functors.ForClosure;
import org.openintents.droidcon.cloud.PMF;

import com.google.appengine.api.datastore.Key;

import javax.jdo.Query;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Schedule {

	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Long id;

	@Persistent
	private String name;

	@Persistent
	private Date date;

	@Persistent
	private long version;

	@Persistent
	private String location;

	@Persistent
	@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "alias asc, name asc"))
	private List<Room> rooms;

	@Persistent
	@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "from asc, to asc"))
	private List<Panel> panels;

	private static SimpleDateFormat df = new SimpleDateFormat("yyyMMDD");

	@NotPersistent
	private static PersistenceManager pm;

	public Long getId() {
		return id;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public long getVersion() {
		return version;
	}

	public void setVersion(long version) {
		this.version = version;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public List<Room> getRooms() {
		return rooms;
	}

	public void setRooms(List<Room> rooms) {
		this.rooms = rooms;
	}

	public List<Panel> getPanels() {
		return panels;
	}

	public void setPanels(List<Panel> panels) {
		this.panels = panels;
	}

	/**
	 * Creates a new Schedule object with the given name
	 * 
	 * @param name
	 *            String with the name of the Schedule, e.g. Google I/O
	 */
	public Schedule(String name) {
		this.setName(name);
	}

	/**
	 * Returns the PersistenceManager for the Schedule Class, creates one if not
	 * existent or closed
	 * 
	 * @return PersistenceManager
	 */
	private static PersistenceManager getPersistenceManager() {
		if (pm == null) {
			pm = PMF.get().getPersistenceManager();
		} else if (pm.isClosed()) {
			pm = PMF.get().getPersistenceManager();
		}
		return pm;
	}

	/**
	 * Finds the Schedule in the database by the given id
	 * 
	 * @param id
	 *            integer with the id of the Schedule
	 * @return Schedule object found in the database
	 */
	public static Schedule find(int id) {
		Schedule schedule = Schedule.getPersistenceManager().getObjectById(
				Schedule.class, id);
		return schedule;
	}

	/**
	 * Makes the Schedule object persistent
	 * 
	 * @return boolean true if successful, false if not
	 */
	public boolean persist() {
		boolean wasSuccessful;
		try {
			version++;
			getPersistenceManager().makePersistent(this);
			wasSuccessful = true;
		} catch (Exception e) {
			wasSuccessful = false;
		} finally {
			getPersistenceManager().close();
		}
		return wasSuccessful;
	}

	/**
	 * Deletes the Schedule object from the persistent storage
	 * 
	 * @return
	 */
	public boolean delete() {
		boolean wasSuccessful;
		try {
			getPersistenceManager().deletePersistent(this);
			wasSuccessful = true;
		} catch (Exception e) {
			wasSuccessful = false;
		} finally {
			getPersistenceManager().close();
		}
		return wasSuccessful;
	}

	/**
	 * Returns all Schedule as a List from the persistent storage
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static List<Schedule> findAll() {
		String sqlFetchAll = "select from " + Schedule.class.getName();
		Query query = Schedule.getPersistenceManager().newQuery(sqlFetchAll);
		List schedules = (List) query.execute();
		return schedules;
	}

	public Room findRoom(long roomId) {
		for (Room r : getRooms()) {
			if (r.getId().getId() == roomId) {
				return r;
			}
		}
		return null;
	}

	public Panel findPanel(long panelId) {
		for (Panel p : getPanels()) {
			if (p.getId().getId() == panelId) {
				return p;
			}
		}
		return null;
	}

	public String getDateString() {
		if (date != null) {
			return df.format(date);
		} else {
			return "";
		}
	}

	public void setDateString(String date) {
		try {
			this.date = df.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

}
